package directory

import (
	"context"
	// "fmt"
	"strconv"
	"strings"
	"time"

	"mall/common/globalkey"
	"mall/service/attachment/model"
	"mall/service/attachment/rpc/internal/svc"
	"mall/service/attachment/rpc/internal/utils/errorhandler"
	"mall/service/attachment/rpc/types/attachment"
	"mall/service/backend/common/errorx"
	"mall/service/backend/common/i18n"

	// "github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

type BackendCreateLogLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewBackendCreateLogLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BackendCreateLogLogic {
	return &BackendCreateLogLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *BackendCreateLogLogic) BackendCreateLog(in *attachment.CreateLogReq) (*attachment.BaseResp, error) {
	// logrus.Info(fmt.Sprintf("BackendCreateLog CreateLogReq: %+v", in))

	var ids []uint64
	var fids []any
	for _, id := range in.FileIds {
		if i, err := strconv.ParseInt(id, 10, 64); err == nil && i > 0 {
			ids = append(ids, uint64(i))
			fids = append(fids, i)
		}
	}

	if len(fids) == 0 {
		return nil, errorx.NewInvalidArgumentError(i18n.ValidationError)
	}

	filterMap := make(map[string]map[string][]any)
	filterMap[model.AttachmentLogColumns.AttachmentID] = map[string][]any{
		"in": fids,
	}
	logs, _, err := l.svcCtx.FileLog.GetList(l.ctx, model.M{
		"latest": "1",
	}, -1, filterMap)
	if err != nil {
		return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
	}

	countMap := make(map[uint64]uint64)
	for _, log := range logs {
		countMap[log.AttachmentID] = log.Count
	}

	tx, err := l.svcCtx.DB.BeginTx(l.ctx, nil)
	if err != nil {
		return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
	}

	var parentId int64
	if in.ParentId != nil && len(*in.ParentId) > 0 {
		if id, err := strconv.ParseInt(*in.ParentId, 10, 64); err == nil && id > 0 {
			parentId = id
		}
	}
	var userId int64
	if in.UserId != nil && len(*in.UserId) > 0 {
		if id, err := strconv.ParseInt(*in.UserId, 10, 64); err == nil && id > 0 {
			userId = id
		}
	}
	var optPut uint32
	if in.Put != nil {
		optPut = *in.Put
	}
	var optThumbnail uint32
	if in.Thumbnail != nil {
		optThumbnail = *in.Thumbnail
	}
	var optWatermark uint32
	if in.Watermark != nil {
		optWatermark = *in.Watermark
	}
	var fileType int32
	var status uint32
	if in.Status != nil {
		status = *in.Status
	} else {
		status = uint32(globalkey.StatusEnabled)
		fileType = l.getFileTypeByQiniuOption(optPut, optThumbnail, optWatermark)
	}
	var key string
	if in.Key != nil {
		key = strings.TrimSpace(*in.Key)
	}
	var items []string
	var style string
	if in.Style != nil {
		style = strings.TrimSpace(*in.Style)
		items = append(items, "thumbnail"+":"+style)
	}
	var termId uint64
	if in.TermId != nil {
		termId = *in.TermId
	}
	var objectId uint64
	if in.ObjectId != nil {
		objectId = *in.ObjectId
	}
	var objectType uint32
	if in.ObjectType != nil {
		objectType = *in.ObjectType
	}
	var title string
	if in.Title != nil {
		title = strings.TrimSpace(*in.Title)
		items = append(items, "title"+":"+title)
	}
	var slug string
	if in.Slug != nil {
		slug = strings.TrimSpace(*in.Slug)
		items = append(items, "slug"+":"+slug)
	}

	for _, id := range ids {
		var log model.AttachmentLog
		log.AttachmentID = id
		log.ParentID = uint64(parentId)
		log.UserID = uint64(userId)
		log.Type = uint8(fileType)
		log.Status = uint8(status)
		log.KeyValue = key
		log.TermID = termId
		log.ObjectID = objectId
		log.ObjectType = uint8(objectType)
		log.MetaValue = strings.Join(items, ";")
		log.CreatedAt = time.Now()
		if count, ok := countMap[id]; ok {
			log.Count = count + 1
		} else {
			log.Count = uint64(1)
		}
		err = l.svcCtx.FileLog.Insert(l.ctx, tx, &log)
		if err != nil {
			tx.Rollback()
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}
	}

	tx.Commit()

	return &attachment.BaseResp{
		Msg: i18n.CreateSuccess,
	}, nil
}

func (l *BackendCreateLogLogic) getFileTypeByQiniuOption(
	optPut uint32,
	optThumbnail uint32,
	optWatermark uint32,
) int32 {
	var fileType int32
	if optPut > 0 {
		if optWatermark > 0 {
			if optThumbnail > 0 {
				fileType = globalkey.AttachmentTypePendingFile
			} else {
				fileType = globalkey.AttachmentTypeWatermarkPendingFile
			}
		} else {
			if optThumbnail > 0 {
				fileType = globalkey.AttachmentTypeThumbnailPendingFile
			} else {
				fileType = globalkey.AttachmentTypePutPendingFile
			}
		}
	} else {
		fileType = globalkey.AttachmentTypeLocalFile
	}

	return fileType
}
